<script lang="ts" setup>
import TableColumn from './TableColumn.vue'
import {IBtnType, IMyTableProps, ITableHeader} from '@/interface/table'
import RightMenu from '@/components/BaseTable/RightMenu.vue'
import {recursivelyAddData} from '@/utils/utils.ts'
import {nextTick, onBeforeMount, ref, watch} from 'vue'
import {getRoleBtn} from '@/utils/tools.ts'

defineOptions({
	name: 'BaseTable'
})

const props = withDefaults(defineProps<IMyTableProps>(), {})
let tableHeaderNew: any = ref([])
const tableRef = ref()
const defaultChecked = ref([])

onBeforeMount(() => {
	tableHeaderNew.value = props.tableHeader
	defaultChecked.value = headDataFilter(tableHeaderNew.value)
})
// 是否显示按钮根据权限来
const isShowBtn = (item: IBtnType, row: any) => {
	const role: boolean = getRoleBtn(item.code || '') // 写一个方法校验是否有这个权限, 有的话返回true, 没有的话返回false
	let validate: boolean = true
	if (item.validate) {
		validate = item.validate(row, item)
	}
	return role && validate
}

// 按钮点击操作事件
const callFn = (item: any) => {
	if (item.method && item.method.constructor === Function) {
		item.method(item)
	}
}

//点击复选框
const handleChange = (obj: any) => {
	tableHeaderNew.value = recursivelyAddData(tableHeaderNew.value, 'childrenList', 'prop', obj.data.prop, 'hidden', !obj.checked)
	defaultChecked.value = headDataFilter(tableHeaderNew.value)
	nextTick(() => {
		tableRef.value.doLayout()
	})
}

// 获取默认选中的唯一值
const headDataFilter = (list: any[], arr: any = []) => {
	const newList = JSON.parse(JSON.stringify(list))
	let returnArr: any = []
	returnArr = returnArr.concat(arr)
	if (!newList.length) return []
	for (const i in newList) {
		const item: ITableHeader = newList[i]
		if (!item.hidden) {
			returnArr.push(item.prop)
		}

		if (item.childrenList && item.childrenList.length) {
			returnArr = headDataFilter(item.childrenList, returnArr)
		}
	}
	return returnArr
}
watch(() => props.tableHeader, (val) => {
	tableHeaderNew.value = val
}, {
	deep: true,
	immediate: true
})
</script>

<template>
	<section>
		<div v-if="outerBtn" :class="['mb-10', otherConfig.outerBtnAlign === 'right' ? 'fl-r' : '']">
			<template v-for="(oBtn, i) in outerBtn">
				<el-button
					v-if="isShowBtn(oBtn, oBtn)"
					:key="i"
					:type="oBtn.type || 'primary'"
					@click="callFn(oBtn)"
				>
					<template #icon>
						<base-icon :icon="oBtn.icon || ''" :size="12"/>
					</template>
					{{ oBtn.name }}
				</el-button>
			</template>
		</div>

		<div class="box">
			<el-table ref="tableRef" v-bind="tableConfig" v-on="tableConfig?.onMethods">
				<el-table-column
					v-if="otherConfig.needIndex" :label="otherConfig.needIndex" :width="otherConfig.indexWidth||55"
					align="center"
					fixed
					type="index"
				/>
				<el-table-column
					v-if="otherConfig.needSelection"
					:selectable="otherConfig.selectable"
					align="center"
					fixed
					type="selection" width="55"
				/>
				<TableColumn :table-header="tableHeaderNew">
					<template v-for="name in Object.keys($slots)" :key="name" #[name]="scope">
						<slot :name="name" v-bind="scope"/>
					</template>
				</TableColumn>
				<template #empty>
					<slot name="empty">暂无数据</slot>
				</template>
				<template #append>
					<slot name="append"/>
				</template>
				<el-table-column
					v-if="innerBtn.length"
					:align="otherConfig.innerBtnCenter || 'center'"
					:fixed="otherConfig.innerBtnFixed"
					:label="otherConfig.innerBtnLabel || '操作'"
					:width="otherConfig.innerBtnWidth || 180"
				>
					<template #default="scope">
						<template v-for="(btn, inx) in innerBtn">
							<el-button
								v-if="isShowBtn(btn, scope.row)"
								:key="inx"
								:style="{color: btn.color || '#1a9bef'}"
								text
								@click="btn.method(scope.row, btn, scope.$index)"
							>
								<template #icon>
									<base-icon :icon="btn.icon || ''" :size="12"/>
								</template>
								{{ btn.name }}
							</el-button>
						</template>
					</template>
				</el-table-column>
			</el-table>
			<right-menu
				v-if="otherConfig.rightMenuShow"
				:default-checked="defaultChecked"
				:head-data="tableHeaderNew"
				@handle-change="handleChange"
			/>
		</div>

		<div v-if="tablePage" :class="['page', otherConfig.tablePageAlign || 'fl-r']">
			<el-pagination
				v-model:current-page="tablePage.currentPage"
				v-model:page-size="tablePage.pageSize"
				:page-sizes="[10, 20, 30, 40, 50, 100]"
				:total="0"
				background
				layout="total, sizes, prev, pager, next, jumper"
				small
				v-bind="tablePage"
				v-on="tablePage"
			/>
		</div>
	</section>
</template>

<style lang="scss" scoped>
.box {
	position: relative;

	.right-menu {
		z-index: 3;
		height: 40px;
	}
}

.page {
	margin: 10px 0 0;
}

.el-button.is-text {
	padding: 0;
}
</style>
